package com.ld.control.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ld.control.business.user.vo.resp.TokenInfoRespVo;
import com.ld.control.exception.BusinessException;
import com.ld.control.sysenum.ResultResponseEnum;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class JWTUtils {

    private static final String requestHead = "usertoken";
    private static final String secret = "ld2024@#123456";
    private static final Long expiration = 604800L;

    @Autowired
    private HttpServletRequest request;

    public Long getCurrentUserAccountId() {
        return getTokenInfo().getUserAccountId();
    }

    /**
     * 生成用户token,设置token超时时间
     */
    public String createToken(Long userAccountId, String accountName) {
        //过期时间
        Date expireDate = new Date(System.currentTimeMillis() + expiration * 1000);
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create()
                // 添加头部
                .withHeader(map)
                //可以将基本信息放到claims中
                //userName
                .withClaim("userAccountId", userAccountId)
                .withClaim("accountName", accountName)
                //超时设置,设置过期的日期
                .withExpiresAt(expireDate)
                //签发时间
                .withIssuedAt(new Date())
                //SECRET加密
                .sign(Algorithm.HMAC256(secret));
        System.out.println(token);
        return token;
    }

    /**
     * 校验token并解析token
     */
    public TokenInfoRespVo getTokenInfo() {
        DecodedJWT jwt;
        String token = request.getHeader(requestHead);
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
            jwt = verifier.verify(token);
            if (jwt.getExpiresAt().before(new Date())) {
                throw new BusinessException("token过期");
            }
            Map<String, Claim> claims = jwt.getClaims();
            Long userAccountId = claims.get("userAccountId").asLong();
            String accountName = claims.get("accountName").asString();
            TokenInfoRespVo tokenInfoRespVo = new TokenInfoRespVo();
            tokenInfoRespVo.setUserAccountId(userAccountId);
            tokenInfoRespVo.setAccountName(accountName);
            return tokenInfoRespVo;
        } catch (Exception e) {
            //解码异常则抛出异常
            //log.error("token解析异常:", e);
            throw new BusinessException(ResultResponseEnum.TOKEN_INVALID);
        }

    }

}
